package statement;

import java.util.ArrayList;
import java.util.List;

import util.Result;
import util.Scope;
import exception.ExpressionException;
import exception.NoMoreStepsException;
import exception.StatementExecutionException;
import expression.Expression;

public class WhileStatement implements Statement {

	private Expression expression;
	private List<Statement> statements;
	private int currentStep;
	private Result result;
	private Scope scope;

	public WhileStatement(Scope scope, Expression expr) {
		this(scope, expr, new ArrayList<Statement>());
	}

	public WhileStatement(Scope scope, Expression expr, List<Statement> stLi) {
		this.expression = expr;
		this.statements = stLi;
		this.currentStep = 0;
		this.result = null;
		this.scope = scope;
	}

	public void addStatement(Statement stat) {
		this.statements.add(stat);
	}

	@Override
	public void execute() throws StatementExecutionException,
			NoMoreStepsException {
//		System.out.println(this);
		try {
			while (true) {
				nextStep();
			}
		} catch (Exception e) {
			// nic nie rob - petla sie skonczyla
		}
	}

	@Override
	public void nextStep() throws StatementExecutionException,
			NoMoreStepsException {
//		System.out.println("PRZED"+this.scope);
		if (this.getConditionValue()) {
			statements.get(currentStep).execute();
			currentStep++;
			if (currentStep >= statements.size()) {
				reset();
			}
		} else {
			throw new NoMoreStepsException();
		}
//		System.out.println("PO"+this.scope);
		}

	public Boolean getConditionValue() {
		if (this.result == null) {
			try {
				this.result = this.expression.evaluate();
			} catch (ExpressionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return (Boolean) this.result.getValue();
	}

	public void reset() {
		this.result = null;
		this.currentStep = 0;
		for(Statement st : this.statements) {
			st.reset();
		}
	}

	public String toString() {
		return "WhileStatement: [ expression: " + this.expression
				+ ", expression result: " + this.result + ", statements: "
				+ this.statements + ", current step: " + this.currentStep
				+ ", current statement: " + this.statements.get(currentStep);
	}
}
